#include "NeoCalendarModel.h"

NeoCalendarModel::NeoCalendarModel(QObject *parent)
    : QAbstractListModel(parent), mDisplayMode(NeoCalendarType::DayView)
{
}

NeoCalendarModel::~NeoCalendarModel() = default;

void NeoCalendarModel::setDisplayMode(NeoCalendarType::DisplayMode mode)
{
    if (mDisplayMode != mode)
    {
        this->beginResetModel();
        mDisplayMode = mode;
        this->endResetModel();
    }
}

int NeoCalendarModel::rowCount(const QModelIndex &parent) const
{
    switch (mDisplayMode)
    {
    case NeoCalendarType::DayView:
    {
        return mYearCount * 12 * 31;
    }
    case NeoCalendarType::MonthView:
    {
        return mYearCount * 12;
    }
    case NeoCalendarType::YearView:
    {
        return mYearCount;
    }
    default:
        break;
    }
    return 0;
}

QVariant NeoCalendarModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole)
    {
        switch (mDisplayMode)
        {
        case NeoCalendarType::DayView:
        {
            return QVariant::fromValue(mBaseDate.addDays(index.row()));
        }
        case NeoCalendarType::MonthView:
        {
            return QVariant::fromValue(mBaseDate.addMonths(index.row()));
        }
        case NeoCalendarType::YearView:
        {
            return QVariant::fromValue(mBaseDate.addYears(index.row()));
        }
        default:
            break;
        }
    }
    return QVariant();
}

QModelIndex NeoCalendarModel::getIndexFromDate(const QDate &date) const
{
    if (!date.isValid())
    {
        return QModelIndex();
    }
    int row = 0;
    switch (mDisplayMode)
    {
    case NeoCalendarType::DayView:
    {
        row = mBaseDate.daysTo(date);
        break;
    }
    case NeoCalendarType::MonthView:
    {
        row = (date.year() - mBaseDate.year()) * 12 + (date.month() - mBaseDate.month());
        break;
    }
    case NeoCalendarType::YearView:
    {
        row = date.year() - mBaseDate.year();
        break;
    }
    default:
        break;
    }
    if (row < 0 || row >= this->rowCount())
    {
        return QModelIndex();
    }
    return index(row, 0);
}

QDate NeoCalendarModel::getDateFromIndex(const QModelIndex &index) const
{
    if (!index.isValid() || index.row() < 0 || index.row() >= this->rowCount())
    {
        return QDate();
    }
    switch (mDisplayMode)
    {
    case NeoCalendarType::DayView:
    {
        return mBaseDate.addDays(index.row());
    }
    case NeoCalendarType::MonthView:
    {
        return mBaseDate.addMonths(index.row());
    }
    case NeoCalendarType::YearView:
    {
        return mBaseDate.addYears(index.row());
    }
    default:
        break;
    }
    return QDate();
}